<!--
 Copyright 2024 Administrator
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
     http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<script setup lang="ts">
defineOptions({
  // eslint-disable-next-line vue/no-reserved-component-names
  name: "Track",
  inheritAttrs: false,
});

import { listSongOptions } from "@/api/application/song";
import {
  addTrack,
  deleteTrack,
  getTrackForm,
  listTracks,
  updateTrack,
} from "@/api/application/track";
import {
  Pic,
  TrackForm,
  TrackQuery,
  TrackVO,
} from "@/api/application/track/type";
import { uploadPic } from "@/api/minio";
import SvgIcon from "@/components/SvgIcon/index.vue";

import { useAudioStore } from "@/store/modules/audio";
import { Delete, InfoFilled, Plus, ZoomIn } from "@element-plus/icons-vue";
import {
  FormRules,
  UploadFile,
  UploadFiles,
  UploadInstance,
  UploadProps,
} from "element-plus";
import { OptionType } from "element-plus/es/components/select-v2/src/select.types";
import { storeToRefs } from "pinia";
import { onMounted, reactive, ref } from "vue";
const store = useAudioStore();
const { currentTime, currentTimeStr, lrcData, lrcText } = storeToRefs(store);

const queryFormRef = ref(ElForm);
const trackFormRef = ref(ElForm);
const queryParams = reactive<TrackQuery>({
  trackName: "",
  pageNum: 1,
  pageSize: 10,
});

const loading = ref(false);
const filterLoading = ref(false);
const dialog = reactive({
  title: "",
  visible: false,
});

const uploadDialog = reactive({
  title: "",
  visible: false,
  active: 1,
});

const upload = ref<UploadInstance>();
const trackList = ref<TrackVO[]>([]);
const songOptions = ref<OptionType[]>([]);
const trackOptions = ref<OptionType[]>([]);
const cateOptions = ref<OptionType[]>([]);

const formData = reactive<TrackForm>({
  title: "",
  desc: "",
  trackIds: [],
  pic: { id: "", url: "", name: "", status: "ready", uid: 0 },
  isActive: true,
  songList: [],
  trackList: [],
});

const tmpPic = ref<Pic>({ id: "", url: "", name: "", status: "ready", uid: 0 });
const removeIds = ref([]); // 删除歌单ID集合 用于批量删除

const total = ref(0); // 数据总数
// 选择表格的行歌单ID
const selectedRowTrackId = ref<number | undefined>();

const validatePic = (rule: any, value: any, callback: any) => {
  console.log(rule, value);
  if (!tmpPic) {
    callback(new Error("请上传图片"));
  } else {
    if (!tmpPic.value.id) {
      uploadPic(tmpPic.value.raw!)
        .then(({ id, url }) => {
          tmpPic.value.id = id;
          tmpPic.value.url = url;
          formData.pic = tmpPic.value!;
          callback();
        })
        .catch((err) => {
          callback(new Error(err));
        });
    } else {
      callback();
    }
  }
};

const rules = reactive<FormRules<any>>({
  pic: [{ required: true, validator: validatePic, trigger: "submit" }],
  title: [{ required: true, message: "请选择歌单", trigger: "blur" }],
});

/**
 * 筛选歌曲名称
 * @param query
 */
const filterTrack = async (query: string) => {
  if (query !== "") {
    filterLoading.value = true;
    songOptions.value = await listSongOptions({
      songName: query,
      pageNum: 1,
      pageSize: 10,
    });

    filterLoading.value = false;
  } else {
    songOptions.value = [];
  }
};

/**
 * 查询
 */
async function handleQuery() {
  // 重置父组件
  loading.value = true;
  try {
    const data = await listTracks(queryParams);
    // trackList.value = data;

    trackList.value = data.list;
    total.value = data.total;
  } catch (error) {
  } finally {
    loading.value = false;
  }
}

/** 重置查询 */
function resetQuery() {
  queryFormRef.value.resetFields();
  handleQuery();
}

/** 行选中 */
function handleSelectionChange(selection: any) {
  removeIds.value = selection.map((item: any) => item.id);
}

/**
 * 打开表单弹窗
 *
 * @param parentId 父歌单ID
 * @param trackId 歌单ID
 */
async function openDialog(trackId?: number) {
  dialog.visible = true;
  if (trackId) {
    dialog.title = "编辑歌单";
    const data = await getTrackForm(trackId);
    Object.assign(formData, data);
    // formData.genre = (data.genre as Category[])?.map((g) => g.id)?.at(0) ?? "";
    //歌曲下拉选项
    songOptions.value =
      data?.songList?.map((song) => ({
        label: song.title,
        value: song.id,
      })) ?? [];
    formData.trackIds = data?.songList?.map((song) => song.id) ?? [];
    tmpPic.value = formData!.pic!;
    console.log(formData, data);
  } else {
    dialog.title = "新增歌单";
  }
}

/** 歌单保存提交 */
function submitForm() {
  trackFormRef.value.validate(async (isValid: boolean) => {
    if (isValid) {
      try {
        // formData.trackList = formData.trackIds

        if (formData.id) {
          await updateTrack(formData.id, formData);
        } else {
          await addTrack(formData);
        }

        ElMessage.success(`${formData.id ? "修改" : "新增"}成功`);

        closeDialog();
        handleQuery();
      } catch (error) {
        throw error;
      } finally {
      }
    }
  });
}

/** 删除歌单 */
function handleDelete(id?: number) {
  const ids = id ?? removeIds.value;
  if (!ids) {
    ElMessage.warning("请勾选删除项");
    return false;
  }

  ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      await deleteTrack(ids);
      ElMessage.success("删除成功");
      handleQuery();
    })
    .catch(() => ElMessage.info("已取消删除"));
}

/** 关闭弹窗 */
function closeDialog() {
  dialog.visible = false;
  resetForm();
}

/** 重置表单 */
function resetForm() {
  trackFormRef.value.resetFields();
  trackFormRef.value.clearValidate();
  formData.pic = tmpPic.value = { url: "", name: "", status: "ready", uid: 0 };

  formData.id = undefined;
}

/**
 * 选择头像
 * @param uploadFile
 */
const avatarFileChange: UploadProps["onChange"] = async (
  uploadFile: UploadFile
) => {
  // uploadFile.url = URL.createObjectURL(uploadFile.raw!);

  tmpPic.value = {
    ...uploadFile,
    id: "",
    url: URL.createObjectURL(uploadFile.raw!),
  };
  console.log(formData.pic, tmpPic.value);
};

//删除头像
function deletePic() {
  tmpPic.value = { url: "", name: "", status: "ready", uid: 0 };
}

const handleAvatarSuccess: UploadProps["onSuccess"] = async (
  response: any,
  uploadFile: UploadFile,
  uploadFiles: UploadFiles
) => {};

const confirmDelPic = async () => {
  console.log("删除");
  await deletePic();
};
const cancelDelPic = () => {};

onMounted(() => {
  handleQuery();
});
</script>

<template>
  <div class="app-container">
    <div class="search-container">
      <el-form ref="queryFormRef" :model="queryParams" :inline="true">
        <el-form-item label="关键字" prop="keywords">
          <el-input
            v-model="queryParams.trackName"
            placeholder="歌单名称"
            clearable
            @keyup.enter="handleQuery"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery"
            ><template #icon><i-ep-search /></template>搜索</el-button
          >
          <el-button @click="resetQuery">
            <template #icon><i-ep-refresh /></template>
            重置</el-button
          >
        </el-form-item>
      </el-form>
    </div>

    <el-card shadow="never" class="table-container">
      <template #header>
        <el-button
          v-hasPerm="['sys:track:create']"
          type="success"
          @click="openDialog(0)"
        >
          <template #icon><i-ep-plus /></template>
          新增</el-button
        >
        <el-button
          v-hasPerm="['sys:track:delete']"
          type="danger"
          :disabled="removeIds.length === 0"
          @click="handleDelete()"
          ><i-ep-delete />删除</el-button
        >
      </template>

      <el-table
        v-loading="loading"
        :data="trackList"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="50" />
        <el-table-column label="id" align="left" width="50" prop="id" />
        <!-- <el-table-column label="歌手" min-width="150">
          <template #default="scope">
            {{
              scope.row.artistList.map((artist: any) => artist.name).join(",")
            }}
          </template>
        </el-table-column> -->
        <el-table-column label="歌单名称" min-width="150">
          <template #default="scope">
            <svg-icon :icon-class="scope.row.icon" />
            {{ scope.row.title }}
          </template>
        </el-table-column>
        <el-table-column label="标签" min-width="150">
          <template #default="scope">
            <el-tag type="info">
              {{
                scope.row.tagList
                  ?.map((tag: any) => tag.categoryName)
                  ?.join(",") ?? ""
              }}</el-tag
            >
          </template>
        </el-table-column>

        <el-table-column label="状态" align="center" width="200">
          <template #default="scope">
            <el-tag v-if="scope.row.isActive" type="success">正常</el-tag>
            <el-tag v-else type="info">禁用</el-tag>
          </template>
        </el-table-column>

        <el-table-column
          label="介绍"
          align="center"
          width="300"
          prop="desc"
          show-overflow-tooltip
        />
        <el-table-column
          label="创建时间"
          align="left"
          width="200"
          prop="createTime"
        />
        <el-table-column fixed="right" align="center" label="操作" width="220">
          <template #default="scope">
            <el-button
              v-if="scope.row.parentId === 0"
              v-hasPerm="['sys:track:create']"
              type="primary"
              link
              size="small"
              @click.stop="openDialog(scope.row.id)"
            >
              <i-ep-plus />新增
            </el-button>

            <el-button
              v-hasPerm="['sys:track:update']"
              type="primary"
              link
              size="small"
              @click.stop="openDialog(scope.row.id)"
            >
              <i-ep-edit />编辑
            </el-button>
            <el-button
              v-hasPerm="['sys:track:delete']"
              type="primary"
              link
              size="small"
              @click.stop="handleDelete(scope.row.id)"
              ><i-ep-delete />
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <template #footer>
        <pagination
          v-if="total > 0"
          v-model:total="total"
          v-model:page="queryParams.pageNum"
          v-model:limit="queryParams.pageSize"
          @pagination="handleQuery"
        />
      </template>
    </el-card>

    <!-- 添加歌单 -->
    <el-dialog
      v-model="dialog.visible"
      :title="dialog.title"
      destroy-on-close
      append-to-body
      width="800px"
      @close="closeDialog"
      :draggable="true"
      top="5vh"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
      <el-form
        ref="trackFormRef"
        :model="formData"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item required label="歌单名称" prop="title">
          <el-input v-model="formData.title" placeholder="请输入歌单名称" />
        </el-form-item>
        <el-form-item label="关联歌曲" prop="trackIds">
          <el-select-v2
            v-model="formData.trackIds"
            style="width: 240px"
            multiple
            filterable
            remote
            :remote-method="filterTrack"
            clearable
            :options="songOptions"
            :loading="filterLoading"
            placeholder="选择歌曲"
          />
        </el-form-item>
        <el-form-item label="封面" prop="pic">
          <div v-show="tmpPic && tmpPic.url" class="avatar-delete-wrapper">
            <img
              crossOrigin="anonymous"
              :src="tmpPic?.url ?? ''"
              class="avatar"
            />
            <span class="avatar-cover-wrapper">
              <el-icon class="avatar-icon avatar-zoomin-icon">
                <ZoomIn />
              </el-icon>
              <el-popconfirm
                placement="right"
                confirm-button-text="是"
                cancel-button-text="否"
                :icon="InfoFilled"
                icon-color="#626AEF"
                title="你确定要删除头像"
                @confirm="confirmDelPic"
                @cancel="cancelDelPic"
              >
                <template #reference>
                  <el-icon class="avatar-icon avatar-delete-icon">
                    <Delete />
                  </el-icon>
                </template>
              </el-popconfirm>
            </span>
          </div>
          <el-upload
            ref="uploadAvatarRef"
            v-show="!(tmpPic && tmpPic.url)"
            class="avatar-uploader"
            v-model="formData.pic"
            method="put"
            accept="image/bmp,image/gif,image/vnd.microsoft.icon,image/jpeg,image/webp"
            :show-file-list="false"
            :auto-upload="false"
            :on-success="handleAvatarSuccess"
            :on-change="avatarFileChange"
          >
            <el-icon class="avatar-uploader-icon">
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>

        <el-form-item label="状态" prop="isActive">
          <el-switch v-model="formData.isActive" />
        </el-form-item>
        <el-form-item label="介绍" prop="introduce">
          <el-input
            type="textarea"
            v-model="formData.desc"
            placeholder="请输入歌单介绍"
            rows="6"
            autosize
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="closeDialog">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<style scoped lang="scss">
.avatar {
  display: block;
  width: 178px;
  height: 178px;
  object-fit: scale-down;
}

.avatar-cover-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  // cursor: default;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  // pointer-events: none;
  width: 100%;
  height: 100%;
  font-size: 20px;
  color: #fff;
  cursor: pointer;
  background-color: var(--el-overlay-color-lighter);
  opacity: 0;
  transition: opacity var(--el-transition-duration);

  .avatar-icon {
    font-size: 20px;
  }

  .avatar-zoomin-icon {
    margin-right: 15px;
  }
}

.avatar-delete-wrapper {
  position: relative;
  border: 1px dashed gray;

  &:hover {
    .avatar-cover-wrapper {
      opacity: 1;
    }
  }
}
</style>

<style lang="scss">
.play-progress {
  margin-bottom: 15px;
}

.avatar-uploader .el-upload {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  width: 178px;
  height: 178px;
  font-size: 28px;
  color: #8c939d;
  text-align: center;
}
</style>
